home *** CD-ROM | disk | FTP | other *** search
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- struc SampleRec
- sname db 16h dup (?)
- length dw ?
- volume dw ?
- repeat dw ?
- replen dw ?
- ends SampleRec
-
- struc Header
- songname db 20 dup (?)
- samples db 31*size SampleRec dup (?)
- songlen db ?
- restart db ?
- sequences db 128 dup (?)
- mk dd ?
- ends Header
-
- ModHeader dw 0 ;; Segment of MOD Header
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
-
- SigCopy db 'PS16■'
- PS16 PS16Header <>
- HeaderSeg dw 0
-
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; MOD_Open - MOD conversion routine. Assumes you know the file is a .MOD.
- ; In : CX:DX - Input MOD filename.
- ; BX:SI - Output PS16 filename.
- ; AX - Memory segment(s) to do conversion (at least 64k).
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ModIn dw 0 ;; MOD input handle.
- ModOut dw 0 ;; PS16 output handle.
- ModTOD dw 0 ;; Top of data.
- proc MOD_Convert near
- push ds es
- mov [cs:ModTOD],ax
- ; ▒▒▒▒▒ Open/create files.
- mov ds,cx ;; Open input MOD.
- mov ax,3D00h
- int 21h
- jb @@Exit
- mov [cs:ModIn],ax
- mov ds,bx ;; Create output PS16.
- mov dx,si
- mov cx,0
- mov ah,3Ch
- int 21h
- mov [cs:ModOut],ax
-
- ; ▒▒▒▒▒ Read and convert module.
- mov ax,cs
- mov ds,ax
- mov es,ax
- call MOD_ReadConvert
-
- ; ▒▒▒▒▒ Close files.
- mov ah,3Eh ;; Close module
- mov bx,[cs:ModIn]
- int 21h
- mov ah,3Eh ;; Close PS16
- mov bx,[cs:ModOut]
- int 21h
- @@Exit: pop es ds
- ret
- endp MOD_Convert
-
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; MOD_ReadConvert - Conversion routine. Must be called by MOD_Open.
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- proc MOD_ReadConvert near
- ; ▒▒▒▒▒ Read module header.
- mov ax,[cs:ModTOD]
- mov [cs:HeaderSeg],ax
- add [cs:ModTOD],size Header/16+1
- mov ds,ax
- mov es,ax
- mov ax,3F00h
- mov bx,[cs:ModIn]
- xor dx,dx
- mov cx,size Header
- int 21h
-
- ; ▒▒▒▒▒ Test for 15 or 31 instrument module.
- cmp [Word ds:Header.mk],'.M'
- jnz @@CheckFLT4
- cmp [Word ds:2+Header.mk],'.K'
- jz @@31Ins
- @@CheckFLT4: cmp [Word ds:Header.mk],'LF'
- jnz @@15Ins
- cmp [Word ds:2+Header.mk],'4T'
- jz @@31Ins
-
- @@15Ins: ; ▒▒▒▒▒ Do 15 instrument conversion to 31 instrument.
- mov si,20+15*30 ;; Copy orders, etc.
- mov di,(offset (Header).songlen)
- mov cx,134
- rep movsb
- mov di,offset Header+20+15*30 ;; Clear out 16-31 ins.
- mov cx,16*30
- mov al,0
- rep stosb
- mov ax,4200h ;; Reposition file ptr.
- mov bx,[cs:ModIn]
- mov cx,0
- mov dx,258h
- int 21h
-
- @@31Ins: ; ▒▒▒▒▒ Convert 31 instrument header to PS16.
- call MOD_ConvertHeader
-
- ; ▒▒▒▒▒ Convert all patterns to PS16 format.
- call MOD_LoadSavePatterns
-
- ; ▒▒▒▒▒ Convert all samples to PS16 format.
- call MOD_LoadSaveSamples
-
- ; ▒▒▒▒▒ Convert all instrument names to PS16 format.
- call MOD_ConvertComments
-
- ; ▒▒▒▒▒ Write final header out.
- mov ax,4200h
- mov bx,[cs:ModOut]
- mov cx,0
- mov dx,0
- int 21h
- mov ax,cs
- mov ds,ax
- mov cx,size PS16Header
- mov dx,offset PS16
- mov ah,40h
- int 21h
-
- ret
- endp MOD_ReadConvert
-
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; MOD_ConvertHeader - Converts the module header to a PS16 header. Called
- ; from MOD_ReadConvert.
- ; In : DS - set to segment of module header.
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- proc MOD_ConvertHeader near
- pusha
- push ds
-
- ; ▒▒▒▒▒ Clear out PS16 Header Data.
- mov ax,cs
- mov es,ax
- mov di,offset PS16
- mov al,0
- mov cx,size PS16Header
- rep stosb
-
- ; ▒▒▒▒▒ Copy Sig and Name to PS16 Header.
- mov di,offset PS16
- mov ax,[Word cs:SigCopy]
- stosw
- mov ax,[Word cs:SigCopy+2]
- stosw
- mov al,[Byte cs:SigCopy+4]
- stosb
- mov si,(offset (Header).songname)
- mov di,offset PS16.SongName
- mov cx,20
- rep movsb
- mov al,26 ;; ^Z terminate it.
- stosb
-
- ; ▒▒▒▒▒ Copy Song Length and Sequences to PS16Header.
- mov al,[ds:Header.songlen]
- mov [es:PS16.SongLen],al
- mov si,(offset (Header).sequences)
- mov di,offset PS16.Sequences
- mov cx,128
- xor ax,ax
- @@SetBlock: mov ah,al
- jmp @@BotLoop
- @@SearchLoop: lodsb
- stosb
- cmp al,ah
- jg @@SetBlock
- @@BotLoop: loop @@SearchLoop
- mov al,ah
- inc al
- mov [es:PS16.numpatterns],al
-
- ; ▒▒▒▒▒ Copy Samples to PS16Header doing any appropriate
- ; ▒▒▒▒▒ fixups as necessary.
- mov bp,31 ;; 31 instruments.
- mov si,(offset (Header).samples)+(offset (SampleRec).length)
- mov di,offset PS16.Samples
- @@FlipLoop: mov ax,[ds:si+4] ;; Get repeat start.
- xchg ah,al ;; Amiga swap.
- mov cx,ax ;; Save.
- mov bx,[ds:si+6] ;; Get repeat length.
- xchg bh,bl ;; Amiga swap.
- add ax,bx ;; Add onto repeat.
- mov dx,[ds:si] ;; Get the length.
- xchg dh,dl ;; Amiga swap.
- cmp ax,dx ;; If the repeat+replen > length...
- jbe @@OKRepeat
- shr cx,1 ;; Then divide the repeat by 2.
- @@OKRepeat: shl dx,1 ;; Multiply the length by 2.
- mov [Word es:di+PS16Sample.length],dx ;; Store it.
- mov ax,[ds:si+2] ;; Get the volume and finetune and
- xchg ah,al ;; swap.
- mov [Word es:di+PS16Sample.volume],ax ;; Store.
- shl bx,1 ;; Multiply the rep len by 2.
- cmp bx,2 ;; If the repeat is <= 2,
- ja @@StoreIt
- mov bx,0 ;; then there isn't one.
- @@StoreIt:
- mov [Word es:di+PS16Sample.replen],bx ;; Store it.
- shl cx,1 ;; Multiply the repeat by 2.
- mov [Word es:di+PS16Sample.repeat],cx ;; Store it.
- mov [Word es:di+PS16Sample.c2freq],8448 ;; C-2 Frequency.
- @@OKSample: add si,size SampleRec ;; Go to next MOD sample.
- add di,size PS16Sample ;; Go to next PS16 sample.
- dec bp ;; T minus bp samples.
- jne @@FlipLoop ;; Continue if not done.
-
- ; ▒▒▒▒▒ Write PS16 Header to file.
- mov bx,[cs:ModOut]
- mov ax,cs
- mov ds,ax
- mov cx,size PS16Header
- mov dx,offset PS16
- mov ah,40h
- int 21h
-
- pop ds
- popa
- ret
- endp MOD_ConvertHeader
-
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; MOD_LoadSavePatterns - Converts MOD patterns to PS16 patterns and saves
- ; them to disk.
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ModPatSeg dw 0
- ModBuf3 dw 0
- LastLine db 0FFh
- proc MOD_LoadSavePatterns near
- ; ▒▒▒▒▒ Allocate buffers.
- mov ax,[cs:ModTOD]
- mov [cs:ModPatSeg],ax ;; 1k MOD pattern buffer.
- add ax,1024/16
- mov [cs:ModBuf3],ax ;; 3K PS16 pattern buffer.
- mov es,ax
-
- mov [cs:LastLine],0FFh
-
- ; ▒▒▒▒▒ Start loop.
- mov cx,0
-
- @@BlockReadLoop:; ▒▒▒▒▒ Read in a pattern.
- push cx
- mov cx,1024
- mov bx,[cs:ModIn]
- mov ax,[cs:ModPatSeg]
- mov ds,ax
- xor dx,dx
- mov ax,3F00h ; Load in the block.
- int 21h
-
- ; ▒▒▒▒▒ Set up for compression.
- mov ax,[cs:ModBuf3] ; Clear pattern of garbage.
- mov es,ax
- mov di,0
- mov cx,3072/2
- mov ax,0
- rep stosw
- mov di,0
- mov ax,0 ; Size of pattern so far.
- stosw
- mov al,64 ; Number of lines in pattern.
- stosb
-
- mov cx,0 ; CX - Number of Channels Done.
- @@ChannelLoop: ; ▒▒▒▒▒ Compress this baby!
- push cx ; Push Number of Channels Done.
- shl cx,2 ; MOD channel offset - Channel*4.
- mov si,cx
- mov cx,0 ; Current line counter (0-63)
- @@LineLoop: push cx
- cmp [Word ds:si],0 ; Is there anything at all to
- jne @@ItsThere ; compress?
- cmp [Word ds:si+2],0
- je @@NothingSkip ; No! Skip compressing this line.
- @@ItsThere: xor dh,dh
- mov dl,cl
- dec dl
- cmp [cs:LastLine],dl
- jne @@WholeLineStore
- mov dh,10000000b
- jmp @@SkipLineStore
- @@WholeLineStore:
- mov al,cl ; Store down the current line.
- stosb
- @@SkipLineStore:mov [cs:LastLine],cl
- call MOD_NoteMatcher ; Find a matching note.
- mov bl,[ds:si] ; Get the hi byte of instrument.
- and bl,0F0h
- shl bl,2 ; Shift it so it will fit in our note.
- or al,bl ; Put 'em together.
- or al,dh ; Put on whether line is continuous.
- stosb ; ...and store it down.
- mov ax,[ds:si+2] ; Also store the lo byte of ins.
- stosw ; and the special effect and data.
- @@NothingSkip: add si,16 ; Go to next MOD pattern line.
- pop cx ; Pop off the line counter.
- inc cx
- cmp cx,64 ; Are we done?
- jne @@LineLoop
- mov al,-1 ; Store a -1 to signify End of Track.
- stosb
- pop cx ; Pop off the Channel Counter.
- inc cx ; Since MODs are only four channels,
- cmp cx,4 ; we only have four channels to
- jnz @@ChannelLoop ; do.
-
- ; ▒▒▒▒▒ Store channels 4-16 as -1's.
- mov cx,4 ; Channel Counter.
- @@CLoop: mov al,-1
- stosb
- inc cx
- cmp cx,16
- jnz @@CLoop
-
- ; ▒▒▒▒▒ Store the new PS16 pattern size in position 0.
- mov bx,di ; Save size.
- mov cx,bx ; Modify it to 16-byte bound.
- and cx,0Fh ; Are lower 4 bits set to anything?
- or cx,cx
- je @@OKSize
- and bx,0FFF0h
- add bx,16
- @@OKSize: add [Word cs:PS16.totalPatternSize],bx
- adc [Word cs:2+PS16.totalPatternSize],0
- mov di,0
- mov cx,bx ; Size for save.
- mov ax,bx
- stosw
-
- ; ▒▒▒▒▒ Write the PS16 pattern to disk.
- mov ax,[cs:ModBuf3]
- mov ds,ax
- mov dx,0
- mov bx,[cs:ModOut]
- mov ah,40h
- int 21h
-
- ; ▒▒▒▒▒ Are we done yet?
- pop cx
- inc cx
- cmp cl,[cs:PS16.numpatterns]
- jnz @@BlockReadLoop
-
- ret
- endp MOD_LoadSavePatterns
-
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; MOD_NoteMatcher - Tries to come up with an equivalent note position as per
- ; the MOD_Match table. For instance, 1712 is 1, 56 is 60
- ; and 0 is 0.
- ; In : DS:SI - MOD note.
- ; Out: AX - Note found (0-61)
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- MOD_Match dw 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,912
- dw 856,808,762,720,678,640,604,570,538,508,480,453
- dw 428,404,381,360,339,320,302,285,269,254,240,226
- dw 214,202,190,180,170,160,151,143,135,127,120,113
- dw 107,101,95,90,85,80,75,71,67,63,60,56,0
- proc MOD_NoteMatcher near
- mov ax,[ds:si] ; Get the note.
- xchg ah,al ; Amiga swap.
- and ax,0FFFh ; We want only the note.
- or ax,ax ; Is there one?
- je @@Done ; NOPE!!!
- mov bx,offset MOD_Match
- mov cx,0 ; Note counter.
- @@NoteMatcher: cmp ax,[cs:bx] ; Do we have a close match?
- jae @@Found ; YES!
- add bx,2 ; Kick our pointer up by a word.
- inc cx ; Increment the note counter.
- cmp cx,61 ; Are we out of notes?
- jnz @@NoteMatcher
- mov ax,0 ; If we made it here, then the note
- ret ; in question was WAY out of range.
- @@Found: mov ax,cx ; Return the result.
- inc ax
- @@Done: ret
- endp MOD_NoteMatcher
-
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; MOD_LoadSaveSamples - Loads and saves the new PS16 samples to disk.
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- proc MOD_LoadSaveSamples near
- mov cx,31
- mov bx,offset PS16.Samples
- @@DoSamples: push cx bx
-
- ; ▒▒▒▒▒ Is this a sample?
- mov cx,[Word cs:bx+PS16Sample.length]
- or cx,cx
- je @@Bottom
-
- ; ▒▒▒▒▒ Load sample.
- mov ds,[cs:ModTOD]
- mov dx,0
- mov bx,[cs:ModIn]
- mov ax,3F00h
- int 21h
-
- ; ▒▒▒▒▒ Convert sample.
- mov es,[cs:ModTOD]
- xor si,si
- xor di,di
- call MOD_ConvertSample
-
- ; ▒▒▒▒▒ Save sample.
- mov ds,[cs:ModTOD]
- mov dx,0
- mov bx,[cs:ModOut]
- mov ah,40h
- int 21h
-
- @@Bottom: pop bx
- add bx,size PS16Sample
- pop cx
- loop @@DoSamples
- ret
- endp MOD_LoadSaveSamples
-
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; MOD_ConvertSample - Converts sample to new format for better compression.
- ; In : DS:SI - Pointer to input sample
- ; ES:DI - Pointer to output sample
- ; CX - Number of bytes to do.
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- proc MOD_ConvertSample
- push cx
- jcxz @@20 ; Abort if nothing to do.
- mov ah, 0
- @@10: lodsb
- mov bl, al
- sub al, ah
- stosb
- mov ah, bl
- loop @@10
- @@20: pop cx
- ret
- endp MOD_ConvertSample
-
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; MOD_ConvertComments - Converts instrument names to comments.
- ; In : DS:SI - Pointer to input sample
- ; ES:DI - Pointer to output sample
- ; CX - Number of bytes to do.
- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- InsText db 'INST',22,31
- proc MOD_ConvertComments
- mov ax,4201h ; Get current position.
- mov bx,[cs:ModOut]
- xor cx,cx
- xor dx,dx
- int 21h
- mov [Word PS16.commentofs],ax ; Store comment ofs.
- mov [Word 2+PS16.commentofs],dx
- mov ax,cs ; Write INST text.
- mov ds,ax
- mov dx,offset InsText
- mov cx,6
- mov ah,40h
- int 21h
- mov ds,[cs:HeaderSeg]
- mov si,(offset (Header).samples)+(offset (SampleRec).sname)
- mov cx,31
- @@CopyIns: push cx
- mov dx,si ; Write sample name.
- mov cx,22
- mov ah,40h
- int 21h
- add si,size SampleRec
- pop cx
- loop @@CopyIns
- ret
- endp MOD_ConvertComments
-